package com.zihan.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zihan.constant.ParamsConstant;
import com.zihan.context.UserContext;
import com.zihan.domain.dto.ProjectDTO;
import com.zihan.domain.entity.*;
import com.zihan.domain.result.PageResult;
import com.zihan.domain.result.Result;
import com.zihan.domain.vo.InvitationVO;
import com.zihan.domain.vo.ProjectVO;
import com.zihan.mapper.ProjectMapper;
import com.zihan.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 科研项目表 服务实现类
 * </p>
 *
 * @author zhangzihan
 * @since 2025-10-20
 */
@Service
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> implements IProjectService {

    @Resource
    private IProjectInvitationService projectInvitationService;
    @Resource
    private IUserService userService;
    @Resource
    private IProjectMemberService projectMemberService;
    @Resource
    private IProjectMilestoneService projectMilestoneService;
    @Resource
    private IProjectMilestoneDocumentService projectMilestoneDocumentService;

    /**
     * 创建项目
     *
     * @param project
     * @return
     */
    @Transactional
    @Override
    public Result<String> create(ProjectDTO project) {
        Long teacherId = UserContext.getCurrentId();
        Project p = new Project();
        BeanUtil.copyProperties(project, p);
        p.setAttachmentUrls(project.getFileUrl());

        // 生成项目编号
        String projectCode = IdUtil.fastUUID();
        p.setProjectCode(projectCode);

        // 获取学生信息
        List<Long> studentIds = project.getStudentIds();
        p.setLeaderId(teacherId);
        save(p);

        // 教师id
        List<ProjectInvitation> invitationList = new ArrayList<>();
        if (!studentIds.isEmpty()) {
            for (Long studentId : studentIds) {
                ProjectInvitation projectInvitation = new ProjectInvitation();
                projectInvitation.setProjectId(p.getId());
                projectInvitation.setInviterId(teacherId);
                projectInvitation.setInviteeId(studentId);
                projectInvitation.setInvitationMessage("请加入我的科研项目");
                projectInvitation.setStatus(0);
                projectInvitation.setExpireTime(LocalDateTime.now().plusDays(3));
                projectInvitation.setCreateTime(LocalDateTime.now());
                projectInvitation.setUpdateTime(LocalDateTime.now());
                projectInvitation.setDeleted(0);
                invitationList.add(projectInvitation);
            }
        }

        projectInvitationService.saveBatch(invitationList);
        return Result.success("创建成功");
    }

    @Override
    public Result<PageResult> getList(ProjectDTO projectDTO) {
        Long teacherId = UserContext.getCurrentId();
        projectDTO.setTeacherId(teacherId);
        Page<Project> page = new Page<>(projectDTO.getPageNo(), projectDTO.getPageSize());
        List<ProjectVO> projectIPage = baseMapper.getList(projectDTO, page);
        // 计算人数和项目节点数

        projectIPage.forEach(projectVO -> {
            Long id = projectVO.getId();
            // 获取参加人数
            Integer memberCount = projectMemberService.lambdaQuery().eq(ProjectMember::getProjectId, id).count();
            projectVO.setProjectMemberNum(memberCount);
            // 获取项目节点数
            Integer milestoneCount = projectMilestoneService.lambdaQuery().eq(ProjectMilestone::getProjectId, id).count();
            projectVO.setProjectMilestoneNum(milestoneCount);
        });
        PageResult pageResult = new PageResult();
        pageResult.setCurrent(page.getCurrent());
        pageResult.setTotal(page.getTotal());
        pageResult.setRecords(projectIPage);
        return Result.success(pageResult);
    }


    // 获取项目详情
    @Override
    public Result<ProjectVO> detail(Long id) {
        Project project = lambdaQuery().eq(Project::getId, id)
                .orderByDesc(Project::getCreateTime)
                .one();
        ProjectVO projectVO = new ProjectVO();
        // 获取项目负责人
        User user = userService.getById(project.getLeaderId());
        projectVO.setTeacherName(user.getUsername());
        // 获取参加人数
        Integer memberCount = projectMemberService.lambdaQuery().eq(ProjectMember::getProjectId, id).count();
        projectVO.setProjectMemberNum(memberCount);
        // 获取项目节点数
        Integer milestoneCount = projectMilestoneService.lambdaQuery().eq(ProjectMilestone::getProjectId, id).count();
        projectVO.setProjectMilestoneNum(milestoneCount);
        BeanUtil.copyProperties(project, projectVO);
        return Result.success(projectVO);
    }


    /**
     * 获取项目成员列表
     *
     * @param id
     * @return
     */
    @Override
    public Result<List<ProjectMember>> member(Long id) {
        List<ProjectMember> projectMemberList = baseMapper.getMemberList(id);
        return Result.success(projectMemberList);
    }


    /**
     * 获取项目节点列表
     *
     * @param projectId
     * @return
     */
    @Override
    public Result<List<ProjectMilestone>> getMilestonDetail(Long projectId) {
        List<ProjectMilestone> projectMilestoneList = baseMapper.getMilestonList(projectId);
        return Result.success(projectMilestoneList);
    }


    /**
     * 删除项目节点
     *
     * @param id
     * @return
     */
    @Transactional
    @Override
    public Result<String> deleteMilestone(Long id) {
        if (Objects.isNull(id)) {
            return Result.error(ParamsConstant.PARAMS_ERROR);
        }
        // 删除节点
        projectMilestoneService.removeById(id);
        // 删除节点下的文档
        projectMilestoneDocumentService.remove(new QueryWrapper<ProjectMilestoneDocument>().eq("milestone_id", id));
        return Result.success("删除成功");
    }


    // 更新项目信息
    @Override
    public Result<String> updateProject(ProjectDTO project) {
        Project p = new Project();
        BeanUtil.copyProperties(project, p);
        p.setAttachmentUrls(project.getFileUrl());
        this.updateById(p);
        return Result.success("更新成功");
    }

    @Override
    public Result<String> deleteByProjectId(Long id) {
        removeById(id);
        // 删除
        projectMilestoneService.remove(new LambdaQueryWrapper<>(ProjectMilestone.class).eq(ProjectMilestone::getProjectId, id));
        projectMilestoneDocumentService.remove(new LambdaQueryWrapper<>(ProjectMilestoneDocument.class).eq(ProjectMilestoneDocument::getProjectId, id));
        return Result.success("删除成功");
    }


    /**
     * 邀请学生
     *
     * @param params
     * @return
     */
    @Override
    public Result<String> invite(JSONObject params) {
        // 获取参数
        List<Long> studentIds = params.getJSONArray("studentIds").toJavaList(Long.class);
        if (studentIds.isEmpty()) {
            return Result.error("请选择学生");
        }
        Long projectId = params.getLong("projectId");
        if (Objects.isNull(projectId)) {
            return Result.error("请选择项目");
        }
        String message = params.getString("message");
        List<ProjectInvitation> invitationList = studentIds.stream().map(studentId -> {
            ProjectInvitation invitation = new ProjectInvitation();
            invitation.setProjectId(projectId);
            invitation.setInviterId(UserContext.getCurrentId());
            invitation.setInviteeId(studentId);
            invitation.setInvitationMessage(message);
            invitation.setStatus(0);
            invitation.setExpireTime(LocalDateTime.now().plusDays(3));
            invitation.setCreateTime(LocalDateTime.now());
            invitation.setUpdateTime(LocalDateTime.now());
            invitation.setDeleted(0);
            return invitation;
        }).collect(Collectors.toList());

        // 排除已经邀请过，且还未过期的学生信息，在项目内的学生，根据项目id，学生id，status查询
        List<ProjectInvitation> hasInvitationList = projectInvitationService.list(new QueryWrapper<ProjectInvitation>());

        invitationList = invitationList.stream().filter(invitation -> {
            return !hasInvitationList.stream().anyMatch(hasInvitation -> {
                return hasInvitation.getProjectId().equals(invitation.getProjectId()) &&
                        hasInvitation.getInviteeId().equals(invitation.getInviteeId())
                        && !Objects.equals(hasInvitation.getStatus(), 4) &&
                        hasInvitation.getExpireTime().isAfter(LocalDateTime.now());
            });
        }).collect(Collectors.toList());
        projectInvitationService.saveBatch(invitationList);

        return Result.success("邀请成功");
    }


    /**
     * 获取邀请学生列表
     *
     * @param projectDTO
     * @return
     */
    @Override
    public Result<PageResult> invitationsStudentList(ProjectDTO projectDTO) {
        Long currentId = UserContext.getCurrentId();
        projectDTO.setStudentId(currentId);
        Page<ProjectInvitation> page = new Page<>(projectDTO.getPageNo(), projectDTO.getPageSize());
        List<InvitationVO> invitationList = baseMapper.invitationsStudentList(projectDTO, page);
        PageResult pageResult = new PageResult();
        pageResult.setCurrent(page.getCurrent());
        pageResult.setTotal(page.getTotal());
        pageResult.setRecords(invitationList);
        return Result.success(pageResult);
    }


    @Override
    public Result<String> acceptInvitation(Long id) {
        if (Objects.isNull(id)) {
            return Result.error(ParamsConstant.PARAMS_ERROR);
        }

        // 查询项目邀请记录是否存在
        ProjectInvitation projectInvitation = projectInvitationService.lambdaQuery().eq(ProjectInvitation::getId, id).one();
        if (Objects.isNull(projectInvitation)) {
            return Result.error("项目邀请记录不存在");
        }
        // 构建成员信息
        Long currentId = UserContext.getCurrentId();
        ProjectMember projectMember = new ProjectMember();
        projectMember.setProjectId(projectInvitation.getProjectId());
        projectMember.setUserId(currentId);
        projectMember.setCreateTime(LocalDateTime.now());
        projectMember.setUpdateTime(LocalDateTime.now());
        projectMember.setJoinTime(LocalDateTime.now());
        projectMember.setDeleted(0);
        // 修改project邀请表状态
        projectInvitation.setStatus(1);
        projectInvitation.setResponseTime(LocalDateTime.now());
        projectInvitation.setResponseMessage("项目邀请已接收");
        projectInvitationService.updateById(projectInvitation);
        projectMemberService.save(projectMember);
        return Result.success("项目邀请已接收");
    }

    @Transactional
    @Override
    public Result<String> refuseInvitation(Long id,String reason) {
        if (Objects.isNull(id)) {
            return Result.error(ParamsConstant.PARAMS_ERROR);
        }

        // 查询项目邀请记录是否存在
        ProjectInvitation projectInvitation = projectInvitationService.lambdaQuery().eq(ProjectInvitation::getId, id).one();
        if (Objects.isNull(projectInvitation)) {
            return Result.error("项目邀请记录不存在");
        }
        // 构建成员信息
        Long currentId = UserContext.getCurrentId();
        ProjectMember projectMember = new ProjectMember();
        projectMember.setProjectId(projectInvitation.getProjectId());
        projectMember.setUserId(currentId);
        projectMember.setCreateTime(LocalDateTime.now());
        projectMember.setUpdateTime(LocalDateTime.now());
        projectMember.setJoinTime(LocalDateTime.now());
        projectMember.setDeleted(0);
        // 修改project邀请表状态
        projectInvitation.setStatus(2);
        projectInvitation.setResponseTime(LocalDateTime.now());
        projectInvitation.setResponseMessage(reason);
        projectInvitationService.updateById(projectInvitation);
        return Result.success("项目邀请已接收");
    }

    @Override
    public Result<List<ProjectMilestone>> getStudentMilestone(Long id) {
        Long currentId = UserContext.getCurrentId();
        List<ProjectMilestone> projectMilestoneList = baseMapper.getStudentMilestonList(id,currentId);
        return Result.success(projectMilestoneList);
    }


    @Override
    public Result<String> uploadMilestone(JSONObject params) {
        Long projectId = params.getLong("projectId");
        Long milestoneId = params.getLong("milestoneId");
        if (Objects.isNull(projectId) || Objects.isNull(milestoneId)) {
            return Result.error(ParamsConstant.PARAMS_ERROR);
        }
        // 获取到url数据
        List<Object> urlList = params.getJSONArray("urlList");
        List<ProjectMilestoneDocument> projectMilestoneDocumentList = urlList.stream().map(url -> {
            ProjectMilestoneDocument projectMilestoneDocument = new ProjectMilestoneDocument();
            projectMilestoneDocument.setMilestoneId(milestoneId);
            projectMilestoneDocument.setProjectId(projectId);

            // 处理LinkedHashMap类型
            if (url instanceof JSONObject) {
                // 如果已经是JSONObject类型
                JSONObject urlObject = (JSONObject) url;
                projectMilestoneDocument.setDocumentName(urlObject.getString("name"));
                projectMilestoneDocument.setDocumentUrl(JSONObject.toJSONString(url));
            } else if (url instanceof java.util.Map) {
                // 如果是Map类型(如LinkedHashMap)
                java.util.Map<String, Object> urlMap = (java.util.Map<String, Object>) url;
                projectMilestoneDocument.setDocumentName((String) urlMap.get("name"));
                projectMilestoneDocument.setDocumentUrl(JSONObject.toJSONString(url));
            } else {
                // 其他情况，转换为JSONObject处理
                JSONObject urlObject = JSONObject.parseObject(JSONObject.toJSONString(url));
                projectMilestoneDocument.setDocumentName(urlObject.getString("name"));
                projectMilestoneDocument.setDocumentUrl(JSONObject.toJSONString(url));
            }

            projectMilestoneDocument.setUploaderId(UserContext.getCurrentId());
            projectMilestoneDocument.setUploadTime(LocalDateTime.now());
            projectMilestoneDocument.setCreateTime(LocalDateTime.now());
            projectMilestoneDocument.setUpdateTime(LocalDateTime.now());
            projectMilestoneDocument.setDeleted(0);
            return projectMilestoneDocument;
        }).collect(Collectors.toList());
        projectMilestoneDocumentService.saveBatch(projectMilestoneDocumentList);
        return Result.success("上传成功");
    }


    @Override
    public Result<String> deleteMilestoneDocument(Long id) {
        projectMilestoneDocumentService.removeById(id);
        return Result.success("删除成功");
    }


    @Transactional
    @Override
    public Result<String> removeMember(Long id) {
        if (Objects.isNull(id)) {
            return Result.error(ParamsConstant.PARAMS_ERROR);
        }
        // 先查询要删除的成员信息
        ProjectMember member = projectMemberService.getById(id);
        if (member == null) {
            return Result.error("成员不存在");
        }
        projectMemberService.removeById(id);
        // 删除邀请表
        projectInvitationService.remove(new QueryWrapper<ProjectInvitation>()
                .eq("invitee_id", member.getUserId()).eq("project_id", member.getProjectId()));
        // 删除该成员上传的文档（基于userId和projectId精确删除）
        projectMilestoneDocumentService.remove(new QueryWrapper<ProjectMilestoneDocument>()
                .eq("uploader_id", member.getUserId())
                .eq("project_id", member.getProjectId()));
        return Result.success("删除成功");
    }


    @Override
    public Result<PageResult> getStudentProject(ProjectDTO projectDTO) {
        Long currentId= UserContext.getCurrentId();
        projectDTO.setStudentId(currentId);
        Page<Project> page = new Page<>(projectDTO.getPageNo(), projectDTO.getPageSize());
        List<ProjectVO> projectIPage = baseMapper.getList(projectDTO, page);
        // 计算人数和项目节点数
        projectIPage.forEach(projectVO -> {
            Long id = projectVO.getId();
            // 获取参加人数
            Integer memberCount = projectMemberService.lambdaQuery().eq(ProjectMember::getProjectId, id).count();
            projectVO.setProjectMemberNum(memberCount);
            // 获取项目节点数
            Integer milestoneCount = projectMilestoneService.lambdaQuery().eq(ProjectMilestone::getProjectId, id).count();
            projectVO.setProjectMilestoneNum(milestoneCount);
            // 获取老师名称
            User user = userService.lambdaQuery().eq(User::getId, projectVO.getLeaderId()).one();
            projectVO.setTeacherName(user.getUsername());

            // 遍历出加入时间
            ProjectMember member = projectMemberService.lambdaQuery().eq(ProjectMember::getProjectId, id)
                    .eq(ProjectMember::getUserId, currentId).one();
            projectVO.setJoinTime(member.getJoinTime());
        });
        PageResult pageResult = new PageResult();
        pageResult.setCurrent(page.getCurrent());
        pageResult.setTotal(page.getTotal());
        pageResult.setRecords(projectIPage);
        return Result.success(pageResult);
    }
}
